<?php
class DB {
    var $__config;
    var $__table;
    function DB($host = "", $database = "", $user = "", $password = "", $newlink = null, $charset = null) {
        $this->__config = array('host' => $host
                , 'db' => $database
                , 'user' => $user
                , 'password' => $password
                , 'charset' => $charset);

        $this->__config['link'] = mysql_connect($host, $user, $password, $newlink) or $this->error();
        mysql_select_db($database, $this->__config['link']);
        // mysql_set_charset($charset, $this->__config['link']);
        if ($charset)
            mysql_query("SET NAMES '$charset'", $this->__config['link']);
    }

    function error() {
        throw new Exception(mysql_error());
    }

    function query($where = null, $tables = null, $order = 'order by id', $limit = 'limit 20') {
        $where_s = "";
        if (!empty ($where))
            $where_s = $this->__general_where($where);

        $from =  "select * from $this->__table ";
        if ($tables) {
            $item = '';
            $table = '';
            foreach($tables as $t => $items) {
                foreach($items as $i) {
                    $item .= " $t.$i,";
                }
                $table .= " $t,";
            }
            $from = "select " . substr($item, 0, -1) . " from " . substr($table, 0, -1) . " ";
        }


        $sql = "$from $where_s  $order $limit";
        return $this->__query($sql, 'Q');
    }

    function update($where, $data) {
        if (empty ($where) == true || empty($data) == true) return false;

        $sql = "update $this->__table set ";

        foreach ($data as $key => $value) {
            $key = mysql_escape_string($key);
            if (is_int($value) || is_float($value)) {
                $sql .= " $key = $value,";
            }
            else {
                $value = mysql_escape_string($value);
                $sql .= " $key = '$value',";
            }
        }

        $sql = substr($sql, 0, -1);

        $sql .= $this->__general_where($where);

        return $this->__query($sql, 'U');

    }

    function insert($data) {
        if (empty($data) == true)
            return false;

        $keys = '';
        $values = '';
        foreach ($data as $key => $value) {

            if ($value == NULL)
                continue;

            $key = mysql_escape_string($key);
            $keys .= " $key,";

            if (is_int($value) || is_float($value)) {
                $values .= " $value,";
            }
            else {
                $value = mysql_escape_string($value);
                $values .= "'$value',";
            }
        }


        $keys = substr($keys, 0, -1);
        $values = substr($values, 0, -1);

        $sql = "insert into $this->__table ($keys) values ($values)";
        return $this->__query($sql, 'I');
    }

    function delete($where) {
        $sql = "delete from $this->__table " . $this->__general_where($where);
        $this->__query($sql, 'D');

    }

    function table($t) {
        $this->__table = $t;
        return $this;
    }

    function tables() {
        $r = $this->__query("show tables", 'Q');
        while ($r->next()) {
            $res[] = $r->__data[0];
        }
        return $res;
    }

    function desc() {
        $r = $this->__query("desc " . $this->__table, 'Q');
        while ($r->next()) {
            $res[$r->Field]["type"] = $r->Type;
            $res[$r->Field]['null'] = $r->Null == 'YES';
            $res[$r->Field]['key'] = $r->Key;
        }
        return $res;
    }

    function __query($sql, $action) {
        //print $sql;
        $res = mysql_query($sql, $this->__config['link'])
                or $this->error();
        if ($action == 'I')
            return mysql_insert_id($this->__config['link']);
        else if ($action == 'Q') {
            return new DBRecord($res, $this);
        }
        else return $res;
    }


    function __general_where($where) {
        $sql = ' where 1 ';
        foreach ($where as $key => $value) {
            if (is_int($key) == false) {
                $key = mysql_escape_string($key);
                if (is_int($value) || is_float($value)) {
                    $sql .= " and $key = $value ";
                }
                else {
                    $value = mysql_escape_string($value);
                    $sql .= " and $key = '$value' ";
                }
            } else {
                $sql .= " and $value ";
            }
        }
        return $sql;
    }

}

class DBRecord {
    var $__res;
    var $__data;
    var $__newdata;
    var $__db;

    function DBRecord($res, $db) {
        $this->__res = $res;
        $this->__db = $db;
    }

    function free() {
        mysql_free_result($this->__res);
    }

    function count() {
        return mysql_num_rows($this-$this->__res);
    }

    function next() {
        $this->__newdata = array();
        $this->__data =  mysql_fetch_assoc($this->__res); // mysql_fetch_array($this->__res);
        return $this->__data !== false;
    }

    function __set($name, $value) {
        $this->__newdata[$name] = $value;
    }

    function __get($name) {
        if (isset ($this->__newdata[$name]))
            return $this->__newdata[$name];
        return $this->__data[$name];
    }

    function save() {
        $this->__db->update(array('id' => $this->id), $this->__newdata);
    }

    function abort() {
        $this->__newdata = array();
    }
}

?>
